//
//  YuanXinCamera.m
//  YuanXinCamera
//
//  Created by 晏德智 on 16/8/18.
//  Copyright © 2016年 晏德智. All rights reserved.
//

#import "YuanXinImagePickerManager.h"

#if __has_include(<React/RCTBridge.h>)
#import <React/RCTBridge.h>
#import <React/RCTConvert.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTUtils.h>
#import <React/RCTImageLoader.h>
#else
#import <React/RCTBridge.h>
#import <React/RCTConvert.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTUtils.h>
#import <React/RCTImageLoader.h>
#endif

#import "TZImagePickerController.h"
#import "PhotoFilterViewController.h"
#import "VideoFilterViewController.h"
#import "Constants.h"
#import "NSObject+AssetsImageManager.h"
#import "YXPhotoPreviewController.h"
#define kAdeleImage @"Bigright"

#import "UrlUtil.h"
#import "UtilFileCache.h"
#import "YXAssetModel.h"
#import "ImageEditorController.h"

typedef NS_ENUM(NSUInteger, CameraType) {
    CameraTypePhoto,
    CameraTypeVideo,
    CameraShowPhoto,
    CameraShowVideo
};

@interface YuanXinImagePickerManager()<UINavigationControllerDelegate,PhotoPreviewImageLoader,ImageEditorDelegate>

/**
 *  返回选择结果类型
 */
@property (nonatomic, strong) NSString *resultContentType;

@property (nonatomic, copy) RCTPromiseResolveBlock success;

@property (nonatomic, copy) RCTPromiseRejectBlock error;

@property (nonatomic, strong) NSString *tagString;

@property (nonatomic, strong) UIImage  *defaultImage;

@property (nonatomic, strong) ImageEditorController *editorVC;

@end

@implementation YuanXinImagePickerManager

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE();

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

#pragma mark - lazy load
- (ImageEditorController *)editorVC {
    if (!_editorVC) {
        _editorVC = [[ImageEditorController alloc] init];
    }
    return _editorVC;
}

/**
 *  调用照像机
 *
 *  @param NSDictionary
 *
 *  @return
 */
RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
    
    self.success = resolve;
    self.error = reject;
    [self mappingParameters:options];
    
}

RCT_EXPORT_METHOD(launchCamera:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
    
    self.success = resolve;
    self.error = reject;
    
    if ([RCTConvert NSUInteger:options[@"IsCamera"]]) {
        
        [self callVideoCamere:options];
        
    }else {
        [self callPhotoCamere:options];
    }
}

RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
    
    self.success = resolve;
    self.error = reject;
    
    if ([RCTConvert NSUInteger:options[@"IsChoose"]]) {
        
        [self showVideoCamere:options];
        
    }else {
        [self showPickPhoto:options withTag:nil];
    }
}

/*
launchCamera =(IsCamera)=>{
    ImageManager.launchCamera({
        IsCamera: IsCamera,// 0 拍照 1录制视频
        maxSecond:6,//录制小视频最长秒数
    }).then(result => {
        // result = {width:240,height:240,type:0,filePath:"/storage/emulated/0/yuanxinpic/1515138201622.png"}
        console.log(result.width+"--"+result.height+"--"+result.filePath);
    }).catch(er => {

    });
 }
 
imagePicker =(isEdite,resultType)=>{
    ImageManager.showImagePicker({
    maxCount: 9,  //最多能选几张 默认是9
    isEdite: isEdite ,//是否剪切 可剪切时 maxCount 只能是 1 多了也没用
    cutWidth:150,//剪切宽度 默认150
    cutHeight:150,//剪切高度 默认150
    resultType:resultType,//object返回一个对象 json返回一个字符串 不填默认object
    tagString:'这里有一个tag',
    }).then(result => {
        if(resultType == 'object'){
        console.log(result.tag+"--"+result.data[0].filePath+"--"+result.data[0].height+"--"+result.data[0].width);
        }else{
            result = JSON.parse(result);
        console.log(result.tag+"--"+result.data[0].filePath+"--"+result.data[0].height+"--"+result.data[0].width);
        }
    }).catch(er => {

    });
}
launchImageLibrary =(isShowCamera,IsChoose)=>{
    ImageManager.launchImageLibrary({
        maxCount: 9,  //最多能选几张 默认是9
        isShowCamera: isShowCamera ,//true显示照相机按钮  false隐藏照相机按钮
        IsChoose:IsChoose,//0是图片 1是视频
        resultType:resultType,//object返回一个对象 json返回一个字符串 不填默认object
    }).then(result => {
        console.log(result[0].filePath+"--"+result[0].height+"--"+result[0].width);
    }).catch(er => {
    });
}
 */

- (void)mappingParameters:(NSDictionary *)options{
    
    self.resultContentType = [RCTConvert NSString:options[@"resultType"]];
    CameraType cameraType = [RCTConvert NSUInteger:options[@"CameraType"]];
    self.tagString = [RCTConvert NSString:options[@"tagString"]];
    switch (cameraType) {
        case CameraTypePhoto:
            [self callPhotoCamere:options];
            break;
        case CameraTypeVideo:
            [self callVideoCamere:options];
            break;
        case CameraShowPhoto:
            //[self OldshowPickPhoto:options];
            [self showPickPhoto:options withTag:self.tagString];
            break;
        case CameraShowVideo:
            [self showVideoCamere:options];
            break;
        default:
            
            break;
    }
    
}


//老的选照片返回参数需要
- (void)OldshowPickPhoto:(NSDictionary *)options {
    TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount: [RCTConvert NSInteger:options[@"maxCount"]]
                                                                                        columnNumber:[RCTConvert NSInteger:options[@"columnNumber"]] delegate:nil];
    
    
    //imagePickerVc.albumPhotoName = [RCTConvert NSString:options[@"photoAlbumName"]];
    imagePickerVc.allowTakePicture =  [RCTConvert NSInteger:options[@"isShowCamera"]]; // 在内部显示拍照按钮
    // 在这里设置imagePickerVc的外观
    // imagePickerVc.navigationBar.barTintColor = [UIColor redColor];
    //     imagePickerVc.oKButtonTitleColorDisabled = [UIColor lightGrayColor];
    //     imagePickerVc.oKButtonTitleColorNormal = [UIColor greenColor];
    
    // YES照片排列按修改时间升序   如果为NO 最近照片在前面拍照按钮在左边
    imagePickerVc.sortAscendingByModificationDate = NO;
    
    imagePickerVc.allowPickingVideo = NO;
    imagePickerVc.allowPickingImage = YES;
    
    
    UIViewController *controller = RCTKeyWindow().rootViewController;
    
    Wk(weakSelf)
    
    // 通过block或者代理，来得到用户选择的照片.
    [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
        
        
        NSMutableArray *pathArr = [[NSMutableArray alloc] init];
        NSMutableArray *dataArr = [[NSMutableArray alloc] init];
        for (int i = 0; i < assets.count;  i++) {
            
            [pathArr addObject:[self.class getAssetURLstrFromAsset:assets[i]]];
            
            NSData*imageData=UIImageJPEGRepresentation(photos[i], 0.3);
            NSString *base64Encoded = [imageData base64EncodedStringWithOptions:0];
            
            [dataArr addObject:base64Encoded];
            
        }
    
        if (dataArr.count == assets.count &&  pathArr.count == assets.count){
            
            if (weakSelf.success) {
                
                if([weakSelf.resultContentType
                    isEqualToString:@"json"]){
                    
                    NSData *jsonPathData = [NSJSONSerialization dataWithJSONObject:pathArr options:NSJSONWritingPrettyPrinted error:nil];
                    NSString *jsonPath = [[NSString alloc] initWithData:jsonPathData encoding:NSUTF8StringEncoding];
                    
                    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataArr options:NSJSONWritingPrettyPrinted error:nil];
                    NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                    weakSelf.success(@{@"data": jsonStr, @"FilePath":jsonPath,@"tag": _tagString});
                }else{
                    weakSelf.success(@{@"data": dataArr, @"FilePath":pathArr,@"tag": _tagString});
                }
            }
        }
        
    }];
    
    
    [controller presentViewController:imagePickerVc animated:YES completion:nil];
}

/**
 *  调用小视频功能
 *
 *  @param NSDictionary {@"maxSecond":@"6",@"videoAlumName":@""};
 @"maxSecond"->最长录制秒数（NSInteger）   @"videoAlumName"->创建的相册名字，默认项目名称,@"smallImageWidth":@""}
 0->照片  1->视频
 *  @return @{@“filePath”:@"本地相册视频路径",@"type":@"1"}
 */

- (void)callVideoCamere :(NSDictionary *)options{
    
    VideoFilterViewController *videoVc = [VideoFilterViewController new];
    
    videoVc.maxRecorderTime = [RCTConvert NSInteger:options[@"maxSecond" ]];
    videoVc.albumName = [RCTConvert NSString:options[@"videoAlumName"]];
    
    //缓存视频到沙盒
    NSString *cacheMovieKey = [[[NSUUID UUID] UUIDString] stringByAppendingString:@".mov"];
    videoVc.cacheMovieKey = cacheMovieKey; // 缓存到沙盒不写入相册
    
    __weak typeof (self) weakSelf = self;
    videoVc.completBlock = ^(NSURL *assetURL)
    {
        if (!assetURL) {
            if (weakSelf.error) {
                weakSelf.error(@"-1", @"录制视频失败", nil);
            }
            return;
        }
        
//        id asset = [self getAssetFromAssetURL:assetURL];
//        NSString *filePath = [self getAssetURLstrFromAsset:asset];
        NSString *filePath = [assetURL path];
        
        UtilFileCache *fileCache = [UtilFileCache instance];
        NSString *cacheThumbnailKey = filePath;
        NSString *cacheThumbnailPath = @"";
        UIImage *firstFrameImage = [self getScreenShotImageFromVideoPath:assetURL];
        CGFloat width = 126;
        CGFloat height = 169;
        if (firstFrameImage) {
            width = firstFrameImage.size.width;
            height = firstFrameImage.size.height;
            NSData *data = UIImagePNGRepresentation(firstFrameImage);
            [fileCache storeFile:data forKey:cacheThumbnailKey withAppendingName:@".png"];
            cacheThumbnailPath = [fileCache cachePathForKey:cacheThumbnailKey withAppendingName:@".png"];
        }
        
        CGFloat duration = [self durationWithVideo:assetURL];
        CGFloat fileSize = [self fileSizeWithVideoUrl:assetURL] / 1024; // Kb
        
        if (weakSelf.success) {
            weakSelf.success(@{
                               @"type":@(1),
                               @"filePath":filePath,
                               @"absoluteFilePath":filePath,
                               @"thumbnail":cacheThumbnailPath,
                               @"width":@(width),
                               @"height":@(height),
                               @"duration":@(ceil(duration)),
                               @"fileSize":@(fileSize),
                               });
        }
    };
    
    UIViewController *controller = RCTPresentedViewController();
    [controller presentViewController:videoVc animated:YES completion:nil];
}


/**
 *  调用拍照功能
 *  0->照片  1->视频
 *  @return NSDictionary @{@"filePath":@"照片存在本地相册路径",@"type":@"0"}
 */

- (void)callPhotoCamere:(NSDictionary *)options {
    
    PhotoFilterViewController *photoVC = [PhotoFilterViewController new];
    photoVC.albumName = [RCTConvert NSString:options[@"photoAlbumName"]];
    
    BOOL isEdit = [RCTConvert BOOL:options[@"isEdite"]];
    BOOL allowEdit = [RCTConvert BOOL:options[@"allowEdit"]] ?: isEdit;
    if (allowEdit) {
        NSDictionary *editConfig = [RCTConvert NSDictionary:options[@"editConfig"]];
        if (editConfig && [[editConfig allKeys] containsObject:@"cropBoxResizeEnabled"]) {
            self.editorVC.cropBoxResizeEnabled = [RCTConvert BOOL:editConfig[@"cropBoxResizeEnabled"]];
        }
    }
    
    __weak typeof (self) weakSelf = self;
    
    photoVC.completBlock = ^(NSURL *assetURL, UIImage *coverImage)
    {
        if (isEdit) {
            self.editorVC.image = coverImage;
            self.editorVC.editorDelegate = self;
            UIViewController *controller = RCTPresentedViewController();
            if (self.editorVC.wetherAddChildEditorVC) {
                [controller presentViewController:self.editorVC animated:YES completion:nil];
            } else {
                [controller.navigationController pushViewController:self.editorVC animated:YES];
            }
        } else {
            if (weakSelf.success) {
                id asset = [self getAssetFromAssetURL:assetURL];
                NSString *filePath = [self.class getAssetURLstrFromAsset:asset];
                
                CGFloat width = coverImage.size.width;
                CGFloat height = coverImage.size.height;
                CGFloat scale = coverImage.scale;
                
                [self.class getAssetAbsolutePathFromAsset:asset resultHandler:^(NSString *path) {
                    NSString *absoluteFilePath = path ?: @"";
                    NSDictionary *temDict = @{
                                              @"type":@(1),
                                              @"filePath":filePath,
                                              @"absoluteFilePath":absoluteFilePath,
                                              @"width":@(width),
                                              @"height":@(height),
                                              @"scale":@(scale)
                                              };
                    
                    weakSelf.success(temDict);
                    
                    temDict = nil;
                }];
            }
        }
    };
    
    UIViewController *controller = RCTPresentedViewController();
    [controller presentViewController:photoVC animated:YES completion:nil];
}


/**
 *  调用选择照片
 *
 *  @param NSDictionary { maxCount:最多选几张，photoAlbumName:内部照相机创建相册名字，showTakePhotoBtn:是否有内部照相机， columnNumber:内部相册分几列显示,@"smallImageWidth":@""} ;
 0->照片  1->视频
 *  @return NSArray @[@{@"type":@"0"，@“filePath” :@""},];
 */
- (void)showPickPhoto:(NSDictionary *)options withTag:(NSString *)tag {
    
    TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount: [RCTConvert NSInteger:options[@"maxCount"]]
                                                                                        columnNumber:[RCTConvert NSInteger:options[@"columnNumber"]] delegate:nil];
    
    
    //imagePickerVc.albumPhotoName = [RCTConvert NSString:options[@"photoAlbumName"]];
    imagePickerVc.allowTakePicture =  [RCTConvert NSInteger:options[@"isShowCamera"]]; // 在内部显示拍照按钮
    // 在这里设置imagePickerVc的外观
    // imagePickerVc.navigationBar.barTintColor = [UIColor redColor];
    //     imagePickerVc.oKButtonTitleColorDisabled = [UIColor lightGrayColor];
    //     imagePickerVc.oKButtonTitleColorNormal = [UIColor greenColor];
    
    // YES照片排列按修改时间升序   如果为NO 最近照片在前面拍照按钮在左边
    imagePickerVc.sortAscendingByModificationDate = NO;
    
    imagePickerVc.allowPickingVideo = NO;
    imagePickerVc.allowPickingImage = YES;
    imagePickerVc.isEdit = [RCTConvert BOOL:options[@"isEdite"]];
    imagePickerVc.allowEdit = [RCTConvert BOOL:options[@"allowEdit"]] ?: imagePickerVc.isEdit;
    if (imagePickerVc.allowEdit) {
        NSDictionary *editConfig = [RCTConvert NSDictionary:options[@"editConfig"]];
        if (editConfig && [[editConfig allKeys] containsObject:@"cropBoxResizeEnabled"]) {
            imagePickerVc.editorVC.cropBoxResizeEnabled = [RCTConvert BOOL:editConfig[@"cropBoxResizeEnabled"]];
        }
    }
    
    __weak typeof (self) weakSelf = self;
    // 通过block或者代理，来得到用户选择的照片.
    [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
        
        if(!photos || photos.count ==0){
            if (weakSelf.error) {
                weakSelf.error(@"-1", @"没有数据", nil);
            }
            return;
        }
        
        [self.class getAssetAbsolutePathArrayFromAssets:assets resultHandler:^(NSArray<NSString *> *result) {
            NSMutableArray *dataArray = [NSMutableArray new];
            for (int i = 0; i < assets.count; i ++) {
                
                UIImage *image = photos[i];
                
                CGFloat width = image.size.width;
                CGFloat height = image.size.height;
                CGFloat scale = image.scale;
                
                NSString *assetURLstr = [self.class getAssetURLstrFromAsset:assets[i]];
                //NSString *absoluteFilePath = [self.class getAssetAbsolutePathFromAsset:assets[i]] ?: @"";
                NSString *absoluteFilePath = result[i];
                NSDictionary *temDict = @{
                                          @"type":@(1),
                                          @"filePath":assetURLstr,
                                          @"absoluteFilePath":absoluteFilePath,
                                          @"width":@(width),
                                          @"height":@(height),
                                          @"scale":@(scale)
                                          };
                [dataArray addObject:temDict];
            }
            if (weakSelf.success) {
                if (tag) {
                    weakSelf.success(@{@"tag": tag, @"data": dataArray});
                } else {
                    weakSelf.success(dataArray);
                }
            }
        }];
    }];
    
    UIViewController *controller = RCTPresentedViewController();
    [controller presentViewController:imagePickerVc animated:YES completion:nil];
}

/**
 *  调用选择视频
 *
 *  @param NSDictionary { maxCount:做多选几张，videoAlumName:内部照相机创建相册名字，showTakePhotoBtn:是否有内部照相机， columnNumber:内部相册分几列显示,@"smallImageWidth":@""} ;
 *   0->照片  1->视频
 *  @return NSArray @[@{@"type":@"1"，@“filePath” :@""},,];
 */
- (void)showVideoCamere:(NSDictionary *)options {
    
    TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount: [RCTConvert NSInteger:options[@"maxCount"]]
                                                                                        columnNumber:[RCTConvert NSInteger:options[@"columnNumber"]] delegate:nil];
    
    //imagePickerVc.albumVideoName = [RCTConvert NSString:options[@"videoAlumName"]];
    imagePickerVc.allowTakePicture =  [RCTConvert NSInteger:options[@"isShowCamera"]];
    
    // YES照片排列按修改时间升序   如果为NO 最近照片在前面拍照按钮在左边
    imagePickerVc.sortAscendingByModificationDate = NO;
    
    //照片和视频不能同时选
    imagePickerVc.allowPickingVideo = YES;
    imagePickerVc.allowPickingImage = NO;
    
    //imagePickerVc.maxRecorderTime = [RCTConvert NSInteger:options[@"maxSecond"]];
    imagePickerVc.videoMaximumDuration = [RCTConvert NSInteger:options[@"maxSecond"]];
    
    __weak typeof (self) weakSelf = self;
    imagePickerVc.didFinishPickingVideoHandle = ^(UIImage *coverImage, PHAsset *asset) {
        // 单选？先模拟下多选情况
        if(coverImage == nil || asset == nil){
            if (weakSelf.error) {
                weakSelf.error(@"-1", @"未获取到视频", [NSError errorWithDomain:AVFoundationErrorDomain code:AVErrorFailedToParse userInfo:nil]);
            }
            return;
        }
        NSArray *photos = @[coverImage];
        NSArray *assets = @[asset];
        
        [self.class getAssetAbsolutePathArrayFromAssets:assets resultHandler:^(NSArray<NSString *> *result) {
            __block NSMutableArray *dataArray = [NSMutableArray new];
            
            for (int i = 0; i <assets.count ; i++) {
                
                UIImage *image = photos[i];
                
                CGFloat width = image.size.width;
                CGFloat height = image.size.height;
                CGFloat scale = image.scale;
                
                NSString *assetURLstr = [self.class getAssetURLstrFromAsset:assets[i]];
                
                // 图片
                UtilFileCache *fileCache = [UtilFileCache instance];
                NSString *cacheThumbnailKey = assetURLstr;
                NSString *cacheThumbnailPath = @"";
                NSData *data = UIImagePNGRepresentation(image);
                [fileCache storeFile:data forKey:cacheThumbnailKey withAppendingName:@".png"];
                cacheThumbnailPath = [fileCache cachePathForKey:cacheThumbnailKey withAppendingName:@".png"];
                
                [self assetInfoWithVideoAsset:assets[i] completion:^(NSDictionary *assetInfo) {
                    CGFloat duration = [assetInfo[@"duration"] floatValue];
                    CGFloat fileSize = [assetInfo[@"fileSize"] longLongValue] / 1024; // Kb
                    
                    NSString *absoluteFilePath = result[i];
                    NSDictionary *temDict = @{
                                              @"type":@(1),
                                              @"filePath":assetURLstr,
                                              @"absoluteFilePath":absoluteFilePath,
                                              @"thumbnail": cacheThumbnailPath,
                                              @"width":@(width),
                                              @"height":@(height),
                                              @"scale":@(scale),
                                              @"duration":@(ceil(duration)),
                                              @"fileSize":@(fileSize),
                                              };
                    [dataArray addObject:temDict];
                    if (dataArray.count == assets.count) {
                        if (weakSelf.success) {
                            weakSelf.success(dataArray);
                        }
                        
                        [dataArray removeAllObjects];
                        dataArray = nil;
                    }
                }];
            }
        }];
    };
    
    UIViewController *controller = RCTPresentedViewController();
    
    [controller presentViewController:imagePickerVc animated:YES completion:nil];
}

//转换绝对路径
RCT_EXPORT_METHOD(getAssetAbsolutePath:(NSString *)str resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
    [self.class getAssetAbsolutePath:str resultHandler:^(NSString *path) {
        if (resolve) {
            resolve(path);
        }
    }];
}
+ (NSString *)getAssetURLstrFromAsset:(id)asset{
    if ([asset isKindOfClass:[ALAsset class]]) {
        //assets-library
        NSURL *assetURL =[asset valueForProperty:ALAssetPropertyAssetURL];
        NSString *imageUrl =[assetURL.absoluteString stringByReplacingOccurrencesOfString:assetURL.scheme withString:@"yuanxin-assets"];
        RCTLog(@"assets-library %@", assetURL.absoluteString);
        
        return imageUrl;
        
    }else if ([asset isKindOfClass:[PHAsset class]]){
        
        PHAsset *phAsset = (PHAsset *)asset;
        //return phAsset.localIdentifier;
        NSString *imageUrl = [NSString stringWithFormat:@"yuanxin-assets://%@",phAsset.localIdentifier];
        RCTLog(@"PHAsset %@", imageUrl);
        
        //[assetURL.absoluteString stringByReplacingOccurrencesOfString:assetURL.scheme withString:@"yuanxin-assets"];
        return imageUrl;
    }
    
    return nil;
}

+ (void)getAssetAbsolutePathArrayFromAssets:(NSArray *)assetArray resultHandler:(void (^)(NSArray<NSString *> *result))resultHandler {
    __block NSMutableArray *result = [NSMutableArray arrayWithArray:assetArray];
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("YuanXin.ImagePicker", DISPATCH_QUEUE_CONCURRENT);
    // 多线程有点问题，可能会造成 result 变为空指针，原因不太明确，还是换种方案遍历吧
//    dispatch_apply(assetArray.count, queue, ^(size_t i){
//        dispatch_group_enter(group);
//        [self getAssetAbsolutePathFromAsset:assetArray[i] resultHandler:^(NSString *path) {
//            NSString *absoluteFilePath = path ?: @"";
//            [result replaceObjectAtIndex:i withObject:absoluteFilePath];
//            dispatch_group_leave(group);
//        }];
//    });
    [assetArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger i, BOOL * _Nonnull stop) {
        dispatch_group_enter(group);
      
        [self getAssetAbsolutePathFromAsset:assetArray[i] resultHandler:^(NSString *path) {
            NSString *absoluteFilePath = path ?: @"";
            [result replaceObjectAtIndex:i withObject:absoluteFilePath];
            dispatch_group_leave(group);
        }];
    }];
    
    dispatch_group_notify(group, queue, ^{
        if(resultHandler){
            resultHandler([result copy]);
        }
    });
}

+ (void)getAssetAbsolutePathFromAsset:(id)asset resultHandler:(void (^)(NSString *path))resultHandler {
     
    if ([asset isKindOfClass:[ALAsset class]]) {
        //assets-library
        NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL];
        NSString *imageUrl = assetURL.absoluteString;
        RCTLog(@"assets-library %@", assetURL.absoluteString);
        
        if (resultHandler) {
            resultHandler(imageUrl);
        }
        
    }else if ([asset isKindOfClass:[PHAsset class]]){
        
        PHAsset *phAsset = (PHAsset *)asset;
        [phAsset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
            // 该block回调总是在主线程(main)上。。所以不能阻塞主线程，不然回调不了。。
            if (resultHandler) {
                NSString *absolutePath = contentEditingInput.fullSizeImageURL.absoluteString;
                if (absolutePath == nil) {
                    // 那应该是视频
                    absolutePath = ((AVURLAsset *)contentEditingInput.audiovisualAsset).URL.absoluteString;
                }
                resultHandler(absolutePath);
            }
        }];
    } else {
        if (resultHandler) {
            resultHandler(nil);
        }
    }
}

+ (void)getAssetAbsolutePath:(NSString *)filePath resultHandler:(void (^)(NSString *path))resultHandler {
    NSString *encodedUrlStr = [UrlUtil encodeUrlString:filePath];
    NSURL *url = [[NSURL alloc] initWithString:encodedUrlStr];
    
    if (url.scheme && [url.scheme caseInsensitiveCompare:@"yuanxin-assets"] == NSOrderedSame){
        
        NSString *assetID;
        if(iOS8Later){
            assetID = [url.absoluteString substringFromIndex:@"yuanxin-assets://".length];
        } else {
            assetID = [url.absoluteString stringByReplacingOccurrencesOfString:url.scheme withString:@"assets-library"];
            
        }
        url = [NSURL URLWithString:assetID];
        
        id asset = [self getAssetFromAssetURL:url];
        [self getAssetAbsolutePathFromAsset:asset resultHandler:^(NSString *path) {
            if (resultHandler) {
                resultHandler(path);
            }
        }];
    } else {
        if (resultHandler) {
            resultHandler(filePath);
        }
    }
}

/**
 *  获取视频的时长
 *
 *  @param videoUrl 视频的路径
 *
 *  @return 视频时长
 */
- (CGFloat)durationWithVideo:(NSURL *)videoUrl{
    
    AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:videoUrl options:nil];
    CMTime audioDuration = audioAsset.duration;
    
    float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
    
    return audioDurationSeconds * 1000; // 向安卓统一，返回毫秒(ms)形式
}

/**
 *  获取视频的时长
 *
 *  @param videoUrl 视频的路径
 *
 *  @return 视频时长
 */
- (long long)fileSizeWithVideoUrl:(NSURL *)videoUrl {
    long long fileSize = 0;
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoUrl options:nil];
    NSArray *arr = [asset tracksWithMediaType:AVMediaTypeVideo];
    AVAssetTrack * track = arr.firstObject;
    if (track != nil) {
        fileSize = track.totalSampleDataLength;
    }
    return fileSize;
}

/**
 *  获取视频的时长
 *
 *  @param asset 视频资源对象
 *
 *  @return 视频相关信息
 */
- (void)assetInfoWithVideoAsset:(id)asset completion:(void (^ __nullable)(NSDictionary *))completion{
    __block long long fileSize = 0;
    __block CGFloat duration = .0;
    NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithObjects:@[@(0), @(0)] forKeys:@[@"duration", @"fileSize"]];
    if ([asset isKindOfClass:AVURLAsset.class]) {
        AVURLAsset *videoAsset = (AVURLAsset *)asset;
        duration = [self durationWithVideo:videoAsset.URL];
        fileSize = [self fileSizeWithVideoUrl:videoAsset.URL];
        infoDict[@"duration"] = [NSNumber numberWithLongLong:duration];
        infoDict[@"fileSize"] = [NSNumber numberWithLongLong:fileSize];
        if (completion) {
            completion(infoDict);
        }
    } else if ([asset isKindOfClass:ALAsset.class]) {
        ALAsset *videoAsset = (ALAsset *)asset;
        duration = [[videoAsset valueForProperty:ALAssetPropertyDuration] floatValue]; //Find the Duraion
        ALAssetRepresentation *rep = [videoAsset defaultRepresentation];
        fileSize = [rep size];
        infoDict[@"duration"] = [NSNumber numberWithLongLong:duration];
        infoDict[@"fileSize"] = [NSNumber numberWithLongLong:fileSize];
        if (completion) {
            completion(infoDict);
        }
    } else if ([asset isKindOfClass:PHAsset.class]) {
        PHAsset *videoAsset = (PHAsset *)asset;
        
        PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
        options.version = PHVideoRequestOptionsVersionOriginal;

        [[PHImageManager defaultManager] requestAVAssetForVideo:videoAsset options:options resultHandler:^(AVAsset *resultAsset, AVAudioMix *audioMix, NSDictionary *info) {
            if ([resultAsset isKindOfClass:[AVURLAsset class]]) {
                AVURLAsset* videoAsset = (AVURLAsset*)resultAsset;
                duration = [self durationWithVideo:videoAsset.URL];
//                NSNumber *size;
//                [videoAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
//                fileSize = size.longLongValue;
                fileSize = [self fileSizeWithVideoUrl:videoAsset.URL];
                infoDict[@"duration"] = [NSNumber numberWithLongLong:duration];
                infoDict[@"fileSize"] = [NSNumber numberWithLongLong:fileSize];
            }
            if (completion) {
                completion(infoDict);
            }
        }];
    }
}

/**
 *  获取视频的缩略图方法
 *
 *  @param filePath 视频的本地路径
 *
 *  @return 视频截图
 */
- (UIImage *)getScreenShotImageFromVideoPath:(NSURL *)videoUrl{
    
    UIImage *shotImage = [[self class] getThumbnailImage:videoUrl second:0.0 maximumSize:CGSizeMake(300, 169)];
    return shotImage;
    
}
+(UIImage *)getThumbnailImage:(NSURL *)videoUrl second:(CGFloat)second maximumSize:(CGSize)maximumSize {
    if (videoUrl) {
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil];
        AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
        // 设定缩略图的方向
        // 如果不设定，可能会在视频旋转90/180/270°时，获取到的缩略图是被旋转过的，而不是正向的
        gen.appliesPreferredTrackTransform = YES;
        // 设置图片的最大size(分辨率)
        gen.maximumSize = CGSizeEqualToSize(maximumSize, CGSizeZero) ? CGSizeMake(300, 169) : maximumSize;
        CMTime time = CMTimeMakeWithSeconds(second, 600); //取第second秒，一秒钟600帧 //缩略图创建时间 CMTime是表示电影时间信息的结构体，第一个参数表示是视频第几秒，第二个参数表示每秒帧数.(如果要获得某一秒的第几帧可以使用CMTimeMake方法)
        NSError *error = nil;
        CMTime actualTime; //缩略图实际生成的时间
        CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
        if (error) {
            return nil;
        }
        UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
        CGImageRelease(image);
        return thumb;
    } else {
        return nil;
    }
}

//浏览图片
RCT_EXPORT_METHOD(showPhotoList:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
    NSDictionary *dict = [RCTConvert NSDictionary:options];
   
    //判断是否存在imageList
    NSArray<YXAssetModel *> *imageModes ;
    if ([[dict allKeys]  containsObject: @"imageList"]){
        imageModes =  [self checkImageURL:[RCTConvert NSArray:dict[@"imageList"] ]] ;
    }
    //判断是否存在imgBase64List
    NSArray<YXAssetModel *> *imageBase64Modes;
    if ([[dict allKeys]  containsObject: @"imgBase64List"]){
        imageBase64Modes =  [self checkImageBase64:[RCTConvert NSArray:dict[@"imgBase64List"] ]] ;
    }
    __block RCTPromiseResolveBlock successCallBack =  nil;
    if(resolve){
        successCallBack = [resolve copy];
    }
    RCTPromiseRejectBlock errorCallBack = nil;
    if(reject){
        errorCallBack = [reject copy];
    }
    //如果没有传入数据，则return
    if((imageModes == nil || [imageModes count]==0) && (imageBase64Modes == nil || [imageBase64Modes count]==0)){
        if(reject){
            errorCallBack(0,@"请输入正确的参数key:imageList|key:imgBase64List，或者数组为空",nil);
        }
        return;
    }
    //默认值等于0，第一张图
    NSInteger showIndex = 0;
    if ([[dict allKeys] containsObject: @"showfirst"]){
        showIndex = [RCTConvert NSInteger:dict[@"showfirst"]];
        showIndex = MAX(MIN(showIndex, imageModes.count - 1), 0);
    }
    
    UIViewController *controller = RCTKeyWindow().rootViewController;
    YXPhotoPreviewController *photoVC = [[YXPhotoPreviewController alloc] init];
    //此参数可以设置从屏幕哪儿个位置出来 一般设置的是点击的view在屏幕的frame 可以不设
    photoVC.tappedThumbnail = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    
    photoVC.showFirstIndex = showIndex;
    photoVC.models = imageModes;
    photoVC.base64Models = imageBase64Modes;
    photoVC.cellImageLoader = self;
    [controller presentViewController:photoVC animated:YES completion:^{
        if(successCallBack){
            successCallBack([NSNumber numberWithBool:YES]);
        }
    }];
}

#pragma mark - ImageEditorDelegate

- (void)imageEditor:(UIViewController *)editor didFinishEdittingWithImage:(UIImage *)image {
    [TZImageManager manager].shouldFixOrientation = YES;
    [[TZImageManager manager] savePhotoWithImage:image completion:^(PHAsset *asset, NSError *error) {
        if (!error && asset) {
            if (self.success) {
                NSString *filePath = [self.class getAssetURLstrFromAsset:asset] ?: @"";
                CGFloat width = image.size.width;
                CGFloat height = image.size.height;
                CGFloat scale = image.scale;
                [self.class getAssetAbsolutePathFromAsset:asset resultHandler:^(NSString *path) {
                    NSString *absoluteFilePath = path ?: @"";
                    NSDictionary *temDict = @{
                                              @"type":@(1),
                                              @"filePath":filePath,
                                              @"absoluteFilePath":absoluteFilePath,
                                              @"width":@(width),
                                              @"height":@(height),
                                              @"scale":@(scale)
                                              };
                    self.success(temDict);
                    temDict = nil;
                }];
            }
        } else {
            if (self.error) {
                self.error(@"-1", error.localizedDescription, error);
            }
        }
    }];
    
}
- (void)imageEditorDidCancel:(UIViewController *)editor {
    if (self.error) {
        self.error(@"-1", @"已取消", nil);
    }
}

#pragma mark - privately

- (NSMutableArray *)checkImageURL:(NSArray *)arr {
    
    NSMutableArray *photoArr = [NSMutableArray new];
    
    for (NSString *urlstr in arr) {
        NSString *encodedUrlStr = [UrlUtil encodeUrlString:urlstr];
        
        YXAssetModel *model = [YXAssetModel new];
        NSURL *url =  [[NSURL alloc] initWithString:encodedUrlStr];
        
        if (url.scheme && [url.scheme caseInsensitiveCompare:@"yuanxin-assets"] == NSOrderedSame){
            
            NSString *assetID;
            if(iOS8Later){
                assetID = [url.absoluteString substringFromIndex:@"yuanxin-assets://".length];
            } else {
                assetID = [url.absoluteString stringByReplacingOccurrencesOfString:url.scheme withString:@"assets-library"];
                
            }
            url = [NSURL URLWithString:assetID];
            
            id asset = [self getAssetFromAssetURL:url];
            
            model.YXAsset = asset;
        }else {
            model.imageURL = url;
        }
        
        [photoArr addObject:model];
        
    }
    
    return photoArr;
}

- (NSMutableArray *)checkImageBase64:(NSArray *)arr {
    NSMutableArray *photoArr = [NSMutableArray new];
    for (NSString *base64Str in arr) {
        YXAssetModel *model = [YXAssetModel new];
        model.imageBase64 =base64Str;
        [photoArr addObject:model];
    }
    return photoArr;
}

#pragma mark --PhotoPreviewImageLoader
- (void)cellLazyImageWithAssetModel:(YXAssetModel *)assetModel
                    completionBlock:(imageLoadCompletionBlock)completionBlock{
    
    __block imageLoadCompletionBlock loadCompleted = completionBlock;
    __weak typeof (self) weakSelf = self;
    __block NSInteger tag = assetModel.selectIndex;
    RCTImageLoaderCompletionBlock loaderCompletionBlock =^(NSError *error, UIImage *image) {
        RCTLog(@"loaderCompletionBlock");
        
        if(!error){
            if(loadCompleted){
                loadCompleted(image,tag);
            }else{
                RCTLog(@"loadCompleted null");
            }
        }else{
            RCTLog(@"loadCompleted error %@",error.localizedDescription);
            if(loadCompleted){
                loadCompleted(weakSelf.defaultImage,tag);
            }else{
                RCTLog(@"loadCompleted null");
            }
        }
    };
    CGSize size =  CGSizeZero;
    NSURLRequest *imageReauest = [NSURLRequest requestWithURL:assetModel.imageURL];
#if __has_include(<React/RCTImageLoader.h>)
    [_bridge.imageLoader loadImageWithURLRequest:imageReauest
                                            size:size
                                           scale:1
                                         clipped:YES
                                      resizeMode:RCTResizeModeStretch
                                   progressBlock:nil
                                partialLoadBlock:nil
                                 completionBlock:loaderCompletionBlock];
#else
    [_bridge.imageLoader loadImageWithURLRequest:imageReauest
                                            size:size
                                           scale:1
                                         clipped:YES
                                      resizeMode:UIViewContentModeScaleToFill
                                   progressBlock:nil
                                 completionBlock:loaderCompletionBlock];
#endif
    
}

-  (UIImage *)defaultImage; {
    
    if (!_defaultImage) {
        _defaultImage = [UIImage imageNamed:@"YuanXinCamera.bundle/place"];
    }
    return _defaultImage;
}

@end

















